package com.mime.qweibo;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;

import android.net.http.AndroidHttpClient;

import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;

import com.mime.qweibo.utils.QHttpUtil;

public class QHttpClient {

	private static final int CONNECTION_TIMEOUT = 20000;

	public QHttpClient() {

	}

	public static String getResponseBody(HttpResponse response) {
		String response_text = null;

		HttpEntity entity = null;

		try {

			entity = response.getEntity();
			response_text = _getResponseBody(entity);
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			if (entity != null) {
				try {
					entity.consumeContent();
				} catch (IOException e1) {

				}
			}
		}
		return response_text;
	}

	private static String _getResponseBody(HttpEntity entity)
			throws IOException, ParseException {
		if (entity == null) {
			throw new IllegalArgumentException("HTTP entity may not be null");
		}
		InputStream instream = entity.getContent();

		if (instream == null) {
			return "";
		}

		if (entity.getContentLength() > Integer.MAX_VALUE) {
			throw new IllegalArgumentException(
					"HTTP entity too large to be buffered in memory");
		}
		String charset = getContentCharSet(entity);
		if (charset == null) {
			charset = HTTP.DEFAULT_CONTENT_CHARSET;
		}
		Reader reader = new InputStreamReader(instream, charset);
		StringBuilder buffer = new StringBuilder();
		try {
			char[] tmp = new char[1024];
			int l;
			while ((l = reader.read(tmp)) != -1) {
				buffer.append(tmp, 0, l);
			}
		} finally {
			reader.close();
		}
		return buffer.toString();
	}

	private static String getContentCharSet(HttpEntity entity)
			throws ParseException {
		if (entity == null) {
			throw new IllegalArgumentException("HTTP entity may not be null");
		}
		String charset = null;
		if (entity.getContentType() != null) {
			HeaderElement values[] = entity.getContentType().getElements();
			if (values.length > 0) {
				NameValuePair param = values[0].getParameterByName("charset");
				if (param != null) {
					charset = param.getValue();
				}
			}
		}
		return charset;
	}
	
	/**
	 * Using GET method.
	 * 
	 * @param url
	 *            The remote URL.
	 * @param queryString
	 *            The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpGet(String url, String queryString) throws Exception {
		String responseData = null;

		if (queryString != null && !queryString.equals("")) {
			url += "?" + queryString;
		}

		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		httpGet.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));

		try {
			HttpResponse response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				System.err.println("HttpGet Method failed: "
						+ response.getStatusLine());
			}
			// Read the response body.
			responseData = getResponseBody(response);
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpClient = null;
		}

		return responseData;
	}

	/**
	 * Using POST method.
	 * 
	 * @param url
	 *            The remote URL.
	 * @param queryString
	 *            The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpPost(String url, String queryString) throws Exception {
		String responseData = null;
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		HttpParams httpParams = new BasicHttpParams();
		httpParams.setParameter("Content-Type", "application/x-www-form-urlencoded");
		HttpConnectionParams.setConnectionTimeout(httpParams, new Integer(CONNECTION_TIMEOUT));
		httpPost.setParams(httpParams);
		if (queryString != null && !queryString.equals("")) {
			List<QParameter> listParams = QHttpUtil.getQueryParameters(queryString);
			MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
			for (QParameter param : listParams) {
				try {
					entity.addPart(param.mName, new StringBody(QHttpUtil.formParamDecode(param.mValue),Charset.forName("UTF-8")));
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					throw new UnsupportedEncodingException();
				}				
			}
			httpPost.setEntity(entity);
		}

		try {
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				System.err.println("HttpGet Method failed: "
						+ response.getStatusLine());
			}
			responseData = getResponseBody(response);
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpClient = null;
		}

		return responseData;
	}

	/**
	 * Using POST method with multiParts.
	 * 
	 * @param url
	 *            The remote URL.
	 * @param queryString
	 *            The query string containing parameters
	 * @param files
	 *            The list of image files
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpPostWithFile(String url, String queryString,
			List<QParameter> files) throws Exception {

		String responseData = null;
		url += '?' + queryString;
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		try {
			List<QParameter> listParams = QHttpUtil.getQueryParameters(queryString);
			MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
			for (QParameter param : listParams) {
				try {
					entity.addPart(param.mName, new StringBody(QHttpUtil.formParamDecode(param.mValue)));
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					throw new UnsupportedEncodingException();
				}
			}
			for (QParameter param : files) {
				File file = new File(param.mValue);
				entity.addPart(param.mName, new FileBody(file));
			}

			httpPost.setEntity(entity);

			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				System.err.println("HttpGet Method failed: "
						+ response.getStatusLine());
			}
			responseData = getResponseBody(response);
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpClient = null;
		}

		return responseData;
	}

}
